﻿using KELT.KELTObjects.ViewportObjectModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Media3D;
using System.Windows.Shapes;

namespace KELT
{
    public class Page : INotifyPropertyChanged
    {
        private String TargetName;
        private Point3D CameraPoint;
        public Transform3DGroup CameraTransform3DGroup;

        private Vector3D CameraRotateAnimationVector;

        public double startTime;
        public double endTime;

        public double rotateStartTime;
        public double rotateEndTime;

        public int indexNumber = 0;

        public Viewport2DVisual3D FrontViusal;

        public Color nowBackgroundColor;
        public Color[] fontColor;
        public int selectNum;
        public bool isAuto = false;
        private string m_testString = "Test";

        public string testString
        {
            get
            {
                return m_testString;
            }

            set
            {
                m_testString = value;
                NotifyPropertyChanged("testString");
            }
        }

        private Image m_img = new Image();

        public Image img
        {
            get
            {
                return m_img;
            }
            set
            {
                m_img = value;
                NotifyPropertyChanged("imgSource");
            }
        }

        public ImageSource imgSource
        {
            get
            {
                return m_img.Source;
            }
        }

       

        public Page()
        {
            CameraPoint = new Point3D(0, 0, 0);
        }

        public Page(TOOL mainContext, int number, double x, double y)
        {
            double changeX = (x * 2 / mainContext.mainViewport.RenderSize.Width - 1) * (0.4 * mainContext.cameraManager.getPoint3D().Z) + mainContext.cameraManager.getPoint3D().X + mainContext.cameraManager.getTranslateTransform().OffsetX;
            double changeY = (y * -2 / mainContext.mainViewport.RenderSize.Height + 1) * (0.24 * mainContext.cameraManager.getPoint3D().Z) + mainContext.cameraManager.getPoint3D().Y + mainContext.cameraManager.getTranslateTransform().OffsetY;
            
            CameraPoint = new Point3D(changeX, changeY, 0);
            CameraRotateAnimationVector = new Vector3D(0, 0, 0);

            indexNumber = number;


            TextBlock textBlock = new TextBlock();
            textBlock.Text = "" + indexNumber;

            Viewbox canvas = new Viewbox();
            TargetName = "Target" + number;
            canvas.Name = "Target" + number;
            canvas.Child = textBlock;

            FrontViusal = new Viewport2DVisual3D();
            FrontViusal = CreateFront(canvas, changeX, changeY, -1);
            
            
            canvas.MouseDown += new MouseButtonEventHandler(mainContext.Object_MouseDown);
            canvas.MouseMove += new MouseEventHandler(mainContext.Object_MouseMove);
            
            mainContext.mainViewport.Children.Insert(0, FrontViusal);

        }

        public bool isSet = false;
        public void ChkObjet(TOOL Context, TimeSpan seekTime)
        {
            if (startTime <= seekTime.TotalSeconds && endTime >= seekTime.TotalSeconds)
            {
                if (!isAuto) return;

                if (isSet) return;
                 
                isSet = false;

                Context.background.Fill = new SolidColorBrush(nowBackgroundColor);
                Random rand = new Random();

                for (int i = 0; i < Context.viewPortMgr.ObjectList.Count; i++)
                {
                    ViewportObj obj = Context.viewPortMgr.ObjectList[i];
                    int selNum = rand.Next(5);
                    while(selNum==selectNum)
                    {
                        selNum = rand.Next(5);
                    }
                    if (fontColor == null) return;
                    Color tcolor = fontColor[selNum];
                    obj.colorBrush.Color = tcolor;
                }



            }
        }
        private Viewport2DVisual3D CreateFront(Viewbox p, double x, double y, double z)
        {
            TranslateTransform3D myTranslateTransform3D = new TranslateTransform3D(x, y, z);

            ScaleTransform3D myScaleTransform3D = new ScaleTransform3D(1, 1, 1);
            myScaleTransform3D.CenterX = CameraPoint.X;
            myScaleTransform3D.CenterY = CameraPoint.Y;
            myScaleTransform3D.CenterZ = CameraPoint.Z;

            RotateTransform3D rotateTransform = new RotateTransform3D();
            rotateTransform.CenterX = CameraPoint.X;
            rotateTransform.CenterY = CameraPoint.Y;
            rotateTransform.CenterZ = CameraPoint.Z;
            rotateTransform.Rotation = new AxisAngleRotation3D { Angle = 0, Axis = new Vector3D(0, 1, 0) };

            Point3DCollection myPoint3DCollection = new Point3DCollection();
            myPoint3DCollection.Add(new Point3D((double)-0.5, 0.5, 0));
            myPoint3DCollection.Add(new Point3D((double)-0.5, -0.5, 0));
            myPoint3DCollection.Add(new Point3D((double)0.5, -0.5, 0));
            myPoint3DCollection.Add(new Point3D((double)0.5, 0.5, 0));

            PointCollection myPointCollection = new PointCollection();
            myPointCollection.Add(new Point(0, 0));
            myPointCollection.Add(new Point(0, 1));
            myPointCollection.Add(new Point(1, 1));
            myPointCollection.Add(new Point(1, 0));

            MeshGeometry3D triangleMesh = new MeshGeometry3D();
            triangleMesh.Positions = myPoint3DCollection;
            triangleMesh.TextureCoordinates = myPointCollection;
            
            triangleMesh.TriangleIndices.Add(0);
            triangleMesh.TriangleIndices.Add(1);
            triangleMesh.TriangleIndices.Add(2);
            triangleMesh.TriangleIndices.Add(0);
            triangleMesh.TriangleIndices.Add(2);
            triangleMesh.TriangleIndices.Add(3);

            DiffuseMaterial myDiffuseMaterial = new DiffuseMaterial(Brushes.Transparent);
            Viewport2DVisual3D.SetIsVisualHostMaterial(myDiffuseMaterial, true);


            CameraTransform3DGroup = new Transform3DGroup();
            CameraTransform3DGroup.Children.Add(myTranslateTransform3D);
            CameraTransform3DGroup.Children.Add(myScaleTransform3D);
            CameraTransform3DGroup.Children.Add(rotateTransform);

            Viewport2DVisual3D v2v3 = new Viewport2DVisual3D();
            v2v3.Transform = CameraTransform3DGroup;
            v2v3.Material = myDiffuseMaterial;
            v2v3.Geometry = triangleMesh;
            v2v3.Visual = p;

            return v2v3;
        }

        #region Get/Set
        public void setXYZ(TOOL mainContext, Size size, double x, double y, double z)
        {
            double changeX = (x * 2 / size.Width - 1) * (0.4 * mainContext.cameraManager.getPoint3D().Z) + mainContext.cameraManager.getPoint3D().X + mainContext.cameraManager.getTranslateTransform().OffsetX;
            double changeY = (y * -2 / size.Height + 1) * (0.24 * mainContext.cameraManager.getPoint3D().Z) + mainContext.cameraManager.getPoint3D().Y + mainContext.cameraManager.getTranslateTransform().OffsetY;

            CameraPoint.X = changeX;
            CameraPoint.Y = changeY;

            (CameraTransform3DGroup.Children.ElementAt(0) as TranslateTransform3D).OffsetX = CameraPoint.X;
            (CameraTransform3DGroup.Children.ElementAt(0) as TranslateTransform3D).OffsetY = CameraPoint.Y;
            (CameraTransform3DGroup.Children.ElementAt(0) as TranslateTransform3D).OffsetZ = z;

        }

        public void setCameraVector(Vector3D v)
        {
            CameraRotateAnimationVector = v;
        }

        public Vector3D getCameraVector()
        {
            return CameraRotateAnimationVector;
        }

        public void setTime(double startTime, double endTime)
        {
            this.startTime = startTime;
            this.endTime = endTime;
        }

        public void setRotateTime(double startTime, double endTime)
        {
            this.rotateStartTime = startTime;
            this.rotateEndTime = endTime;
        }
        
        public string getTargetNmae()
        {
            return TargetName;
        }

        public Point3D getPosition() 
        { 
            return CameraPoint;
        }
        #endregion

        public void NotifyPropertyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

}
